﻿Imports System.Linq.Dynamic
Imports System.Data.DataSet


Public Class BussinesLogicGeneric(Of T)
    Inherits BussinesLogicBase
    Private _DataAccessInstance As DataAccess.DataAccessGeneric(Of T)

    Protected Friend Overridable Function getDataAccesInstance() As DataAccess.DataAccessGeneric(Of T)
        If _DataAccessInstance Is Nothing Then
            _DataAccessInstance = New DataAccess.DataAccessGeneric(Of T)()
        End If
        Return _DataAccessInstance
    End Function

    ''' <summary>
    ''' gets a new where query Expression
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function newQueryExpression() As BussinesLogic.WhereQueryExpression
        Return New BussinesLogic.WhereQueryExpression(EntityBaseInstance)
    End Function

    Protected _getCurrentDTO As T
    ''' <summary>
    ''' Obtiene el DTO actual asociado a la BL
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getCurrentDTO() As T
        If _getCurrentDTO Is Nothing Then
            _getCurrentDTO = getNewDTO()
        End If
        Return _getCurrentDTO
    End Function
     

    Public Sub setDTO(ByVal dto As T)
        _getCurrentDTO = dto
    End Sub

    Public Function getNewDTO() As T
        Return Activator.CreateInstance(Of T)()
    End Function

    Private _EntityBaseInstance As EntityBase
    Private ReadOnly Property EntityBaseInstance As EntityBase
        Get
            If _EntityBaseInstance Is Nothing Then
                _EntityBaseInstance = DirectCast(CObj(getNewDTO()), EntityBase)
            End If
            Return _EntityBaseInstance
        End Get

    End Property

    Public Class RequiredValidation
        Public IsValid As Boolean
        Public InvalidFields As IEnumerable(Of PropertiesAttributes)
        Public Sub New(ByVal list As IEnumerable(Of PropertiesAttributes))
            If list Is Nothing Then
                IsValid = True
                Return
            End If

            Me.InvalidFields = list.Where(Function(x) x.PropertyValue Is Nothing).ToList()

            Me.IsValid = Not InvalidFields.Any()

        End Sub

    End Class

    Public Function isValid(ByVal dto As T) As RequiredValidation
        Dim entBase = CType(CObj(dto), EntityBase)
        Return New RequiredValidation(entBase.getRequiredFields())
    End Function

    Public Function isUniqueValidation(ByVal dto As T, Optional ByVal OmitCurrentDTO As Boolean = False) As UniqueFieldsException
        Dim entBase = CType(CObj(dto), EntityBase)

        Dim list = entBase.getUniqueFields()
        If (list Is Nothing OrElse Not list.Any()) Then
            Return Nothing
        End If

        Dim listaDeCamposDuplicados = New List(Of PropertiesAttributes)
        For Each item In list



            Dim lista As Generic.List(Of T)

            If item.UniqueField.CondicionFija.IsNothing() = False Then
                lista = Me.getListFiltered(item.FieldMappingAtt.DbFieldMapp, item.PropertyValue, item.UniqueField.CondicionFija)
            Else
                lista = Me.getListFiltered(item.FieldMappingAtt.DbFieldMapp, item.PropertyValue)
            End If

            If lista IsNot Nothing AndAlso lista.Any() Then
                If OmitCurrentDTO Then
                    If entBase.getPrimaryKeyProperty().PropertyValue <> _
                    CType(CObj(lista(lista.Count - 1)), EntityBase).getPrimaryKeyProperty().PropertyValue Then
                        listaDeCamposDuplicados.Add(item)
                    End If
                Else
                    listaDeCamposDuplicados.Add(item)
                End If

            End If
        Next

        If Not listaDeCamposDuplicados.Any() Then
            Return Nothing
        End If




        Return New UniqueFieldsException(listaDeCamposDuplicados)

    End Function


    Public Overridable Function Add(ByVal objectEntity As T, Optional ByVal mtd As AfterAddDelegate = Nothing) As T
        Try
            If mtd IsNot Nothing Then
                mtd(objectEntity)
            End If
            Dim rfv = isValid(objectEntity)
            If rfv.IsValid Then
                Dim ValidacionDeUnicos = isUniqueValidation(objectEntity)
                If ValidacionDeUnicos Is Nothing Then

                    Dim id = getDataAccesInstance.Add(objectEntity)
                    _getCurrentDTO = Load(id)
                    objectEntity = _getCurrentDTO
                    Return _getCurrentDTO
                Else
                    Throw ValidacionDeUnicos
                End If

            Else
                Throw New RequiredFieldsException(rfv.InvalidFields)
            End If

        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Public Overridable Function AddCurrentDTO() As T
        Return Add(getCurrentDTO())
    End Function


    Private _getCurrentEntityPropertiesAttributes As Dictionary(Of String, PropertiesAttributes)
    Public Function getCurrentEntityPropertiesAttributes() As Dictionary(Of String, PropertiesAttributes)
        If _getCurrentEntityPropertiesAttributes Is Nothing Then
            _getCurrentEntityPropertiesAttributes = CType(CObj(getCurrentDTO()), Entity.EntityBase).PropertiesAttributes()
        End If
        Return _getCurrentEntityPropertiesAttributes
    End Function


    Public Function getPrimaryKeyPropertiesAttributes() As PropertiesAttributes
        Return CType(CObj(getCurrentDTO()), Entity.EntityBase).getPrimaryKeyProperty
    End Function

    Public Function getClassAttributes() As SelfMappClassAttribute
        Return EntityBaseInstance.ClassAttribute()
    End Function

    Public Function getCascadeDeleting() As List(Of CascadeDelettingAttribute)
        Return EntityBaseInstance.getCascadeDeleteAttributes()
    End Function


    Public Function getValueFromClassName(ByVal className As String, ByVal valueTOMap As Object, ByVal propertyName As String) As Object
        Dim inst = ReflectionHelper.GetEntityClassInstance(className)


        Dim obj = BussinesLogicGenericHelper.getBussinesLogicGeneric(className)

        If Not GetType(EntityBase).IsAssignableFrom(inst.GetType()) Then
            Throw New ApplicationException(" la clase " & className & " para " & GetType(T).FullName & " no implementa EntityBase")
        End If

        Dim paramName = DirectCast(inst, EntityBase).PropertiesAttributes().Where(Function(x) x.Value.PropertyName.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)).Select(Function(x) x.Value.FieldMappingAtt.DbFieldMapp).FirstOrDefault()
        If paramName Is Nothing Then
            Throw New ApplicationException("El nombre del parámetro " & propertyName & " de la clase " & className & " para " & GetType(T).FullName & " no es encontrado")
        End If

        Dim list = obj.getListFiltered(paramName, valueTOMap)
        If list IsNot Nothing AndAlso list.Count > 0 Then
            Return CType(list(0), EntityBase).DataTextField
        Else
            Return Nothing
        End If
    End Function

    Public Function getForeingClassMappingValue(ByVal propertyItem As PropertiesAttributes) As Object
        Return Me.getValueFromClassName(propertyItem.ForeingClassMapping.MappingClassName, propertyItem.PropertyValue, propertyItem.ForeingClassMapping.MappingPropertyName)

    End Function

    Public Function getMultiInputForeingClassMappingAttribute(ByVal propertyItem As PropertiesAttributes, ByVal classInstance As T) As Object


        Dim thisClassInstance = DirectCast(CObj(classInstance), EntityBase)
        Dim otherClassInstance = DirectCast(ReflectionHelper.GetEntityClassInstance(propertyItem.MultiInputForeingClassMapping.MappingClassName), EntityBase)
        Dim que As New WhereQueryExpression(otherClassInstance)
        For Each item In propertyItem.MultiInputForeingClassMapping.MappingPropertiesName
            Dim thisClassProperty As PropertiesAttributes
            Dim otherClassProperty As PropertiesAttributes
            Dim v = item.Split(":"c)

            thisClassProperty = thisClassInstance.PropertiesAttributes().Where(Function(x) x.Value.PropertyName.Equals(v(0), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault().Value

            otherClassProperty = otherClassInstance.PropertiesAttributes().Where(Function(x) x.Value.PropertyName.Equals(v(1), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault().Value

            que.FieldName(otherClassProperty.FieldMappingAtt.DbFieldMapp, thisClassProperty.PropertyType).isEqual().ToValue(thisClassProperty.PropertyValue).And()
        Next


        Dim bl = BussinesLogicGenericHelper.getBussinesLogicGeneric(otherClassInstance.GetType().FullName)
        Dim l = bl.getList(que)
        If l IsNot Nothing AndAlso l.Count > 0 Then
            Return DirectCast(CObj(l(0)), EntityBase).DataTextField
        Else
            Return Nothing
        End If


    End Function

    Public Delegate Sub BeforeAddDelegate(ByVal DTOobject As T)
    Public Delegate Sub BeforeUpdateDelegate(ByVal DTOobject As T)
    Public Delegate Sub BeforeDeleteDelegate(ByVal DTOobject As T)
    Public Delegate Sub AfterAddDelegate(ByVal DTOobject As T)
    Public Delegate Sub AfterUpdateDelegate(ByVal DTOobject As T)
    Public Delegate Sub AfterDeleteDelegate(ByVal DTOobject As T)

    Public Overridable Sub BeforeAdd(ByVal DTOobject As T)

    End Sub

    Public Overridable Sub AfterAdd(ByVal DTOobject As T)

    End Sub

    Public Overridable Sub BeforeUpdate(ByVal DTOobject As T)

    End Sub

    Public Overridable Sub AfterUpdate(ByVal DTOobject As T)

    End Sub


    Protected Friend Sub DeleteCascade(ByVal className As String, ByVal idx As Object, ByVal paramName As String)


        Dim obj = BussinesLogicGenericHelper.getBussinesLogicGeneric(className)

        Dim list = obj.getListFiltered(paramName, idx)

        Dim lPK As New List(Of Object)
        For Each item In list
            Dim o = DirectCast(item, EntityBase)
            Dim idxs = o.getCurrentPrimaryKeyValue()
            obj.Delete(idxs)
        Next



    End Sub


    Private Function getDataTableStructure() As DataSet
        Dim key As String = "getDataTableStructure"
        Dim value = CacheMannager.getFromCache(Of BussinesLogicGeneric(Of T), DataSet)(key)
        Dim dt As New DataTable
        If value Is Nothing Then

            If EntityBaseInstance.PropertiesAttributes().Where(Function(x) x.Value.isListViewPart IsNot Nothing).Any() Then

                Dim partDef = EntityBaseInstance.getListPartFields()
                Dim mustAddID As Boolean = False

                mustAddID = Not partDef.Where(Function(x) x.PrimaryKeyAtt IsNot Nothing).Any()

                If mustAddID Then
                    Dim dc As DataColumn

                    dc = New DataColumn(EntityBaseInstance.getPrimaryKeyProperty().LabelAtt.Text, getTypeNullable(EntityBaseInstance.getPrimaryKeyProperty().PropertyType))
                    dt.Columns.Add(dc)
                End If
                For Each item In partDef
                    Dim dc As DataColumn
                    If item.ForeingClassMapping IsNot Nothing OrElse item.MultiInputForeingClassMapping IsNot Nothing Then
                        If item.ForeingClassMapping IsNot Nothing Then
                            dc = New DataColumn(item.LabelAtt.Text, GetType(String))
                        Else
                            dc = New DataColumn(item.MultiInputForeingClassMapping.Label, GetType(String))
                        End If

                    Else
                        dc = New DataColumn(item.LabelAtt.Text, getTypeNullable(item.PropertyType))
                    End If
                    dt.Columns.Add(dc)
                Next
            Else
                'Dim ds As New DataSet
                Dim partDef = EntityBaseInstance.PropertiesAttributes().Values
                For Each item In partDef
                    Dim dc As DataColumn
                    If item.ForeingClassMapping IsNot Nothing OrElse item.MultiInputForeingClassMapping IsNot Nothing Then
                        If item.ForeingClassMapping IsNot Nothing Then
                            dc = New DataColumn(item.LabelAtt.Text, GetType(String))
                        Else
                            dc = New DataColumn(item.MultiInputForeingClassMapping.Label, GetType(String))
                        End If

                    Else
                        dc = New DataColumn(item.LabelAtt.Text, getTypeNullable(item.PropertyType))
                    End If
                    dt.Columns.Add(dc)
                Next
            End If
            Dim ds As New DataSet
            ds.Tables.Add(dt)
            CacheMannager.SetInCache(Of BussinesLogicGeneric(Of T), DataSet)(key, ds, 40)
            value = ds
        End If

        Return value
    End Function

    Public Function getListDataSource(Optional ByVal rowfrom As Integer = 0, _
                                      Optional ByVal rowto As Integer = 0, _
                                      Optional ByVal OrderBy As String = Nothing, _
                                      Optional ByVal query As WhereQueryExpression = Nothing) As DataSet


        Dim l As IEnumerable(Of T)
        Dim recordCount As Double = 0
        If query Is Nothing Then
            If rowto = 0 AndAlso rowfrom = rowto Then
                l = Me.getList()
                recordCount = l.Count()
            Else
                Dim prs = Me.getList(rowfrom, rowto, OrderBy)
                l = prs.List
                recordCount = prs.RecordCount
            End If

        Else
            If rowto = 0 AndAlso rowfrom = rowto Then
                l = Me.getList(query)
                recordCount = l.Count()
            Else

                Dim prs = Me.getList(query, rowfrom, rowto, OrderBy)
                l = prs.List
                recordCount = prs.RecordCount
            End If

        End If

        Dim ds As New DataSet
        Dim dt = getDataTableStructure().Tables(0).Clone()
        ds.Tables.Add(dt)
        If l.Any() Then

            If EntityBaseInstance.getListPartFields() IsNot Nothing Then



                Dim mustAddID As Boolean = False

                mustAddID = Not EntityBaseInstance.getListPartFields().Where(Function(x) x.PrimaryKeyAtt IsNot Nothing).Any()

                For Each linea In l.Select(Function(y) New With {.PK = DirectCast(CObj(y), EntityBase).getPrimaryKeyProperty(), .Fields = DirectCast(CObj(y), EntityBase).getListPartFields(), .TClass = y})
                    Dim dr = dt.NewRow()
                    Dim value As Object
                    If mustAddID Then
                        value = linea.PK.PropertyValue
                        dr(linea.PK.LabelAtt.Text) = IIf(value Is Nothing, DBNull.Value, value)

                    End If
                    For Each x In linea.Fields

                        If x.ForeingClassMapping IsNot Nothing Then
                            value = getForeingClassMappingValue(x)

                        ElseIf x.MultiInputForeingClassMapping IsNot Nothing Then
                            value = getMultiInputForeingClassMappingAttribute(x, linea.TClass)
                        Else

                            value = x.PropertyValue
                        End If
                        If x.MultiInputForeingClassMapping IsNot Nothing Then
                            dr(x.MultiInputForeingClassMapping.Label) = value
                        Else
                            dr(x.LabelAtt.Text) = IIf(value Is Nothing, DBNull.Value, value)

                        End If

                    Next
                    dt.Rows.Add(dr)
                Next

            Else
                For Each linea In l.Select(Function(x) New With {.props = DirectCast(CObj(x), EntityBase).PropertiesAttributes().Values, .TClass = x})
                    Dim dr = dt.NewRow()

                    For Each x In linea.props
                        Dim value As Object
                        If x.ForeingClassMapping IsNot Nothing Then
                            value = Me.getForeingClassMappingValue(x)
                        ElseIf x.MultiInputForeingClassMapping IsNot Nothing Then
                            value = Me.getMultiInputForeingClassMappingAttribute(x, linea.TClass)
                        Else
                            value = x.PropertyValue
                        End If
                        dr(x.LabelAtt.Text) = value
                    Next
                    dt.Rows.Add(dr)
                Next


            End If
        End If
        ds.Tables.Add(New DataTable("RecordCount"))
        ds.Tables(1).Columns.Add(New DataColumn("RecordCount", GetType(Double)))
        ds.Tables(1).Rows.Add(recordCount)

        Return ds

    End Function
    Public Overridable Sub DeleteLogical(ByVal dto As T, Optional ByVal mtd As AfterUpdateDelegate = Nothing)
        Try
            Dim objEnti As EntityBase
            objEnti = CType(CObj(dto), EntityBase)
            If objEnti.getDisableProperty() IsNot Nothing Then
                Brainworklite.Core.ReflectionHelper.SetEntityValue(dto, objEnti.getDisableProperty().PropertyName, objEnti.getDisableProperty().DisableElementAtt.DisabledValue)
                UpdateWithOutValidation(dto)


                Dim ListaCascada = getCascadeDeleting()

                If ListaCascada IsNot Nothing Then


                    For Each item In ListaCascada

                        Dim idx = ReflectionHelper.GetEntityValue(dto, item.ThisPropertyName)

                        Dim obj = BussinesLogicGenericHelper.getBussinesLogicGeneric(item.TableName)

                        Dim list = obj.getListFiltered(item.ForingIDName, idx)

                        For Each itemADeshablitiar In list
                            obj.DeleteLogical(itemADeshablitiar)
                        Next
                    Next
                End If
                Return

            End If

            Throw New ApplicationException("No se ha definido una instancia de eliminación lógica")

        Catch ex As Exception
            Throw ex
        End Try
    End Sub


    Public Overridable Sub Delete(ByVal idx As Object, Optional ByVal mtd As AfterUpdateDelegate = Nothing)
        Try
            If mtd IsNot Nothing Then
                Dim obect As T = Me.Load(idx)
                mtd(obect)
            End If
            If getCascadeDeleting() IsNot Nothing Then

                For Each item In getCascadeDeleting()
                    DeleteCascade(item.TableName, idx, item.ForingIDName)
                Next
            End If

            getDataAccesInstance().Delete(idx, getPrimaryKeyPropertiesAttributes().FieldMappingAtt.DbFieldMapp, getClassAttributes().TableName)

        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Public Sub CleanCurrentDTO()
        _getCurrentDTO = Nothing
    End Sub


    Public Function Load(ByVal PrimaryKeyValue As Object) As T
        Try
            Dim propName = getPrimaryKeyPropertiesAttributes().FieldMappingAtt.DbFieldMapp
            Dim propValue = PrimaryKeyValue 'getPrimaryKeyPropertiesAttributes().PropertyValue
            ' Dim pType As Type = getPrimaryKeyPropertiesAttributes().PropertyType
            'propValue = PrimaryKeyValue
            Dim tableName = getClassAttributes().TableName
            Return Load(tableName, propName, propValue)
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Public Function LoadCurrentDTO(ByVal PrimaryKeyValue As Object) As T
        Me._getCurrentDTO = Load(PrimaryKeyValue)
        Return Me._getCurrentDTO
    End Function

    Public Function Load() As T
        Try

            Dim propName = getPrimaryKeyPropertiesAttributes().PropertyName
            Dim propValue = getPrimaryKeyPropertiesAttributes().PropertyValue
            Dim tableName = getClassAttributes().TableName
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Public Function Load(ByVal TableName As String, ByVal PrimaryKeyFieldName As String, ByVal PrimaryKeyValue As Object) As T
        Try
            Dim da = getDataAccesInstance()

            Return da.getOneByID(PrimaryKeyValue, PrimaryKeyFieldName, TableName)

        Catch ex As Exception
            Throw ex
        End Try
    End Function



    Public Function getEntityBaseList() As List(Of Entity.EntityBase)

        Return getList().Select(Function(x) DirectCast(CObj(x), Entity.EntityBase)).ToList()

    End Function

    Public Overridable Function UpdateCurrentDTO() As T
        Return Update(getCurrentDTO())
    End Function
    Public Overridable Function Update(ByVal obect As T, Optional ByVal mtd As AfterUpdateDelegate = Nothing) As T
        Try
            If mtd IsNot Nothing Then
                mtd(obect)
            End If
            Dim rfv = isValid(obect)
            If rfv.IsValid Then

                Dim ValidacionDeUnicos = isUniqueValidation(obect, True)
                If ValidacionDeUnicos Is Nothing Then

                    Dim da = getDataAccesInstance()
                    Dim PrimaryKeyName = DirectCast(CObj(obect), Entity.EntityBase).getPrimaryKeyProperty().FieldMappingAtt.DbFieldMapp
                    Dim TableName = DirectCast(CObj(obect), Entity.EntityBase).ClassAttribute.TableName
                    da.Update(obect, PrimaryKeyName, TableName)
                    Return obect
                Else
                    Throw ValidacionDeUnicos
                End If


            Else
                Throw New RequiredFieldsException(rfv.InvalidFields)
            End If

        Catch ex As Exception
            Throw ex
        End Try

    End Function


    Public Overridable Function UpdateWithOutValidation(ByVal obect As T, Optional ByVal mtd As AfterUpdateDelegate = Nothing) As T
        Try
            If mtd IsNot Nothing Then
                mtd(obect)
            End If 
                    Dim da = getDataAccesInstance()
                    Dim PrimaryKeyName = DirectCast(CObj(obect), Entity.EntityBase).getPrimaryKeyProperty().FieldMappingAtt.DbFieldMapp
                    Dim TableName = DirectCast(CObj(obect), Entity.EntityBase).ClassAttribute.TableName
                    da.Update(obect, PrimaryKeyName, TableName)
                    Return obect
               

             
        Catch ex As Exception
            Throw ex
        End Try

    End Function



    Public Function GetDisabledField(ByVal dto As T) As PropertiesAttributes
        Dim o = CType(CObj(dto), EntityBase)
        Return o.getDisableProperty()
    End Function



    Public Function getList(ByVal qq As WhereQueryExpression) As List(Of T)
        Dim dp = GetDisabledField(Me.getCurrentDTO())
        If dp IsNot Nothing Then
            qq.And().FieldName(Of String)(dp.FieldMappingAtt.DbFieldMapp).isDistinct().ToValue(dp.DisableElementAtt.DisabledValue)
        End If

        Dim exResult = qq.getExpression()
        If (exResult.WhereSql.Equals("Where", StringComparison.InvariantCultureIgnoreCase)) Then
            Return getDataAccesInstance.getList()
        Else
            Return getDataAccesInstance.getList(exResult.WhereSql, exResult.Parameters)
        End If



    End Function

    Public Function getDataTextValueList(Optional ByVal qq As WhereQueryExpression = Nothing) As List(Of Object)
        Dim l As IEnumerable(Of T)

        If qq Is Nothing Then

            Return getList(New WhereQueryExpression(Me.EntityBaseInstance)).Cast(Of Object)()
            'l = getDataAccesInstance.getList()
        Else

            Dim dp = GetDisabledField(Me.getCurrentDTO())
            qq.And().FieldName(Of String)(dp.FieldMappingAtt.DbFieldMapp).isDistinct().ToValue(dp.DisableElementAtt.DisabledValue)
            Dim exResult = qq.getExpression()
            l = getDataAccesInstance.getList(exResult.WhereSql, exResult.Parameters)
        End If


        Dim l2 = l.Cast(Of EntityBase)().Select(Function(x) New With {.DataValueField = x.DataValueField, .DataTextField = x.DataTextField}).Cast(Of Object)()


        Return l2.ToList()

    End Function

    Public Function getDataTable(filters As Object) As DataTable
        Dim d = getDataAccesInstance().getDataTable(filters)
        Return d
    End Function


    Public Function getDataTable() As DataTable
        Dim d = getDataAccesInstance().getDataTable()
        Return d
    End Function


    Public Function getList(ByVal AnonimousObject As Object) As List(Of T)
        Dim dp = GetDisabledField(Me.getCurrentDTO())
        'qq.And().FieldName(Of String)(dp.PropertyName).isDistinct().ToValue(dp.PropertyValue)
        If dp IsNot Nothing Then
            Return getDataAccesInstance.getList(AnonimousObject).Where( _
                Function(x) dp Is Nothing _
                    OrElse _
                    CType(CObj(x), EntityBase).PropertiesAttributes.Where( _
                       Function(y) y.Key.Equals(dp.FieldMappingAtt.DbFieldMapp, StringComparison.InvariantCultureIgnoreCase) _
                           ).FirstOrDefault().Value IsNot dp.DisableElementAtt.DisabledValue).ToList()
        Else
            Return getDataAccesInstance.getList(AnonimousObject)
        End If

    End Function

    Public Function getList() As List(Of T)

        Return getList(New WhereQueryExpression(Me.EntityBaseInstance))
        'Return getDataAccesInstance.getList()
    End Function
    Public Function getList(ByVal rowFrom As UInt16, ByVal rowTo As UInt32, Optional ByVal OrderByField As String = Nothing) As PagedResults(Of T)
        If OrderByField Is Nothing OrElse String.IsNullOrEmpty(OrderByField.Trim()) Then
            OrderByField = getPrimaryKeyPropertiesAttributes().FieldMappingAtt.DbFieldMapp
        End If
        Return getList(New WhereQueryExpression(Me.EntityBaseInstance), rowFrom, rowTo, OrderByField)
    End Function

    Public Function getList(ByVal qq As WhereQueryExpression, ByVal rowFrom As UInt16, ByVal rowTo As UInt32, Optional ByVal OrderByField As String = Nothing) As PagedResults(Of T)

        Dim dp = GetDisabledField(Me.getCurrentDTO())
        If dp IsNot Nothing Then
            qq.And().FieldName(Of String)(dp.FieldMappingAtt.DbFieldMapp).isDistinct().ToValue(dp.DisableElementAtt.DisabledValue)
        End If

        Dim exResult = qq.getExpression()
        Return getDataAccesInstance.getList(exResult.WhereSql, rowFrom, rowTo, OrderByField, exResult.Parameters)
    End Function

    Public Function getListFiltered(ByVal FieldName As String, ByVal value As Object) As List(Of T)
        Dim dp = GetDisabledField(Me.getCurrentDTO())
        If dp IsNot Nothing Then
            Return getDataAccesInstance.getListFiltered(FieldName, value).Where( _
                Function(x) dp Is Nothing _
                    OrElse _
                    CType(CObj(x), EntityBase).PropertiesAttributes.Where( _
                       Function(y) y.Key.Equals(dp.FieldMappingAtt.DbFieldMapp, StringComparison.InvariantCultureIgnoreCase) _
                           ).FirstOrDefault().Value IsNot dp.DisableElementAtt.DisabledValue).ToList()
        Else
            Return getDataAccesInstance.getListFiltered(FieldName, value)
        End If

    End Function

    Protected Friend Function getListFiltered(ByVal FieldName As String, ByVal value As Object, ByVal conditions As String) As List(Of T)
        Dim dp = GetDisabledField(Me.getCurrentDTO())
        If dp IsNot Nothing Then
            Return getDataAccesInstance.getListFiltered(FieldName, value, conditions).Where( _
                Function(x) dp Is Nothing _
                    OrElse _
                    CType(CObj(x), EntityBase).PropertiesAttributes.Where( _
                       Function(y) y.Key.Equals(dp.FieldMappingAtt.DbFieldMapp, StringComparison.InvariantCultureIgnoreCase) _
                           ).FirstOrDefault().Value IsNot dp.DisableElementAtt.DisabledValue).ToList()
        Else
            Return getDataAccesInstance.getListFiltered(FieldName, value, conditions)
        End If

    End Function



End Class
